package com.xmx.usercenter.controller;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xmx.common.config.WxResponseCode;
import com.xmx.common.utils.IPUtils;
import com.xmx.usercenter.dto.UserInfo;
import com.xmx.usercenter.dto.WxLoginInfo;
import com.xmx.usercenter.feign.OauthClientFeign;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import com.xmx.usercenter.entity.MemberEntity;
import com.xmx.usercenter.service.MemberService;
import com.xmx.common.utils.PageUtils;
import com.xmx.common.utils.R;
import io.swagger.annotations.Api;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;


/**
 * 会员表
 *
 * @author fbb
 * @email boyinbing@126.com
 * @date 2021-08-11 01:37:12
 */
@Api(tags = "MemberController", description = "会员表 服务")
@RestController
@RequestMapping("usercenter/member")
@Slf4j
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Resource
    private WxMaService wxService;

    @Resource
    OauthClientFeign oauthClientFeign;

//    private final PasswordEncoder passwordEncoder;
//
//    public MemberController(PasswordEncoder passwordEncoder) {
//        this.passwordEncoder = passwordEncoder;
//    }

    /**
     * 列表
     */
    @GetMapping("/list")
    //@RequiresPermissions("usercenter:member:list")
    @ApiOperation("获取所有会员表 信息")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = memberService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @GetMapping("/info/{id}")
    //@RequiresPermissions("usercenter:member:info")
    @ApiOperation("获取指定id的会员表 详情")
    public R info(@PathVariable("id") Integer id){
		MemberEntity member = memberService.getById(id);

        return R.ok().put("member", member);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    @ApiOperation("添加会员表 信息")
    //@RequiresPermissions("usercenter:member:save")
    public R save(@RequestBody MemberEntity member){
		memberService.save(member);

        return R.ok();
    }

    /**
     * 修改
     */
    @PutMapping("/update")
    @ApiOperation("更新指定id会员表 信息")
    //@RequiresPermissions("usercenter:member:update")
    public R update(@RequestBody MemberEntity member){
        boolean b = memberService.updateById(member);

        return R.ok().put("data",b);
    }

    /**
     * 删除
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除指定id会员表 信息")
    //@RequiresPermissions("usercenter:member:delete")
    public R delete(@RequestBody Integer[] ids){
		memberService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    @GetMapping("/getUserInfoByUsername")
    public R getUserInfoByUsername(@RequestParam("username")String username){
        QueryWrapper<MemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MemberEntity::getUsername,username);
        List<MemberEntity> one = memberService.list(queryWrapper);
        return R.ok().put("data",one);
    }

    @PostMapping("/login_by_weixin")
    public R  loginByWeixin( @RequestBody WxLoginInfo map, HttpServletRequest request)  {
        // TODO:  1、获取用户信息
        UserInfo userInfo1 = map.getUserInfo();
        String code = map.getCode();
        // TODO:  2、校验code的有效性
        String openId =null;
        String sessionKey = null;
//        log.error("userInfo=====>>>{}::code======>>>{}",userInfo1,code);
        try {
            WxMaJscode2SessionResult session = this.wxService.getUserService().getSessionInfo(code);
            openId = session.getOpenid();
            sessionKey = session.getSessionKey();
            log.info(session.getOpenid());
            log.info(session.getSessionKey());
            if(ObjectUtils.isEmpty(openId) || ObjectUtils.isEmpty(sessionKey)){
                R.error(WxResponseCode.AUTH_OPENID_BINDED.getCode(),WxResponseCode.AUTH_OPENID_BINDED.getMsg());
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        // TODO:  3 判断用户是否存在
        // TODO:  不存在则添加用户到数据库
        // TODO:  存在则更新用户的openId
        MemberEntity data = memberService.getUserInfoByOpenId(openId);
//        MemberEntity data = MapUtil.get(userInfoByOpenId, "data", MemberDto.class);
        if(data==null){
            data = new MemberEntity();
            data.setUsername(openId)
                    .setWeixinOpenid(openId)
                    .setPassword(new BCryptPasswordEncoder().encode(openId))
                    .setGender(userInfo1.getGender())
                    .setLastLoginTime(LocalDateTime.now())
                    .setLastLoginIp(IPUtils.getIpAddr(request))
                    .setUserLevel(0)
                    .setNickname(userInfo1.getNickName())//.substring(0,userInfo1.getNickName().length()-2))
                    .setAvatar(userInfo1.getAvatarUrl())
                    .setWeixinOpenid(openId)
                    .setSessionKey(sessionKey)
                    .setMobile("")
                    .setStatus(0);
            memberService.save(data);
//          新用户发放优惠券

        }else {
            data.setLastLoginTime(LocalDateTime.now())
                    .setLastLoginIp(IPUtils.getIpAddr(request))
                    .setNickname(userInfo1.getNickName())
                    .setSessionKey(sessionKey);
            boolean b = memberService.updateById(data);
            if(!b){
                return R.error("更新异常");
            }
        }

        // TODO:  发放token

        Map<String,String> tokenParam = new HashMap<>();
        Map<String,Object> result = new HashMap<>();
        tokenParam.put("grant_type","password");
        tokenParam.put("client_id","ndmall-weapp");
        tokenParam.put("client_secret","123456");
        tokenParam.put("scope","all");
        tokenParam.put("username",openId);
        tokenParam.put("password",openId);

        log.error("===============================>>>{}",new BCryptPasswordEncoder().encode(openId));
        // TODO:  远程调用认证服务器获取token
        R postAessToken = oauthClientFeign.postAessToken(tokenParam);
        log.error("===============================>>>{}",postAessToken);

        Map<String,Object> userinfo = new HashMap<>();
        userinfo.put("nickName", userInfo1.getNickName());
        userinfo.put("avatarUrl",userInfo1.getAvatarUrl());
        result.put("userInfo",userinfo);
        result.put("token",postAessToken.get("token"));
        result.put("refresh_token",postAessToken.get("refresh_token"));

        return R.ok().put("data",result);
    }

    @PostMapping("/logout")
    public R logout(){
        R logout = oauthClientFeign.logout();
        return logout;
    }

    @PostMapping("token")
    public R reflashtoken(@RequestParam Map<String,Object> map){
        return R.ok();
    }
}
